package br.ufc.great;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;

import android.app.Activity;
import android.app.Dialog;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.gesture.GestureOverlayView.OnGestureListener;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.GestureDetector.OnDoubleTapListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;

public class MActivity extends MapActivity implements OnClickListener,
		OnItemClickListener{

	/*BEGIN Variáveis Controle do Mapa*/
	protected MapView myMap;
	protected CheckBox markMap;
	private MapController mapController;
	protected LocationManager locationManager;
	LocationOverlay myOverlay;
	int currentPositionNote;
	String stringProvider;
	List<String> listDistinct;
	/*END Variáveis Controle do Mapa*/
	
	/*BEGIN Variáveis de Evento*/
	Button bt_listarNotas;
	Button bt_edit, bt_edit_cancel;
	ImageButton bt_editar_nota, bt_excluir_nota, bt_share_facebook, bt_find_aprox_locales;
	Dialog listaDeNotas, dialogEditNote, menuNota;
	ListView listViewNotas;
	TextView tv_title_nota, tv_desc_nota, tv_date_nota;
	EditText et_title_edit, et_desc_edit, et_date_edit;
	/*END Variáveis de Evento*/
	
	/*BEGIN Variáveis do alerta de proximidade*/
	private static final long MINIMUM_DISTANCECHANGE_FOR_UPDATE = 1; // in Meters
    private static final long MINIMUM_TIME_BETWEEN_UPDATE = 1000; // in Milliseconds
    private static final long POINT_RADIUS = 2000; // in Meters
    private static final long PROX_ALERT_EXPIRATION = -1; 
    private static final String PROX_ALERT_INTENT = "br.ufc.great.ProximityAlert";
    ProximityIntentReceiver proximityReceiver = new ProximityIntentReceiver();
    /*END Variáveis do alerta de proximidade*/
    private long lastTouchTime = -1;
    /*BEGIN Variáveis de Persistência*/
    protected static final String DbName = "notes";
    /*END Variáveis de Persistência*/
    
    /*BEGIN Variáveis sem Classe*/
    List<String> listTitulos, listDesc, listDate;
    /*END Variáveis sem Classe*/
    
    
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		// zerarBanco();

		myMap = (MapView) findViewById(R.id.myMap);
		bt_listarNotas = (Button) findViewById(R.id.bt_listarnotas);
		locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
		stringProvider = locationManager.getBestProvider(new Criteria(), true);

		mapController = myMap.getController();

		locationManager.requestLocationUpdates(stringProvider, MINIMUM_TIME_BETWEEN_UPDATE, 
				MINIMUM_DISTANCECHANGE_FOR_UPDATE,	new LocationListenerMap(mapController));

		markMap = (CheckBox) findViewById(R.id.putMarks);
		markMap.setOnClickListener((android.view.View.OnClickListener) new MyOnClickListener());

		bt_listarNotas.setOnClickListener(this);
		
		povoarMapa();

		
	}

	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}

	public void updateLocation(Location l) {

	}

	public void povoarMapa() {
		
		myOverlay = new LocationOverlay(getResources().getDrawable(
				R.drawable.point_marker), this);
		myMap.getOverlays().add(myOverlay);
		mapController.setZoom(13);

		myMap.setBuiltInZoomControls(true); // Setar o zoom para o usuário
											// escolher
		
		/* Povoar mapa com pontos salvos */
		List<String> listGeoPointsInString = lerTudoBanco();
		listDistinct = new ArrayList<String>();

		/*Na forma de armazenar no banco, é utilizado o GEoPoint.toString como chave seguido de t para título, d para descrição e h para data e hora, por isso o uso do listDistinct, pois há o mesmo ponto salvo 3 vezes.*/
		for (int i = 0; i < listGeoPointsInString.size(); i++) {
			String key = listGeoPointsInString.get(i).substring(0, listGeoPointsInString.get(i).length() - 1);
			System.out.println("Key: " + key);
			if (!listDistinct.contains(key)) {
				listDistinct.add(key);

			}
		}
		if (listDistinct.size() > 0) {
			for (int i = 0; i < listDistinct.size(); i++) {
				String[] latAndLng = listDistinct.get(i).split(","); //Separa a lat e a lng.

				int latitudeE6 = Integer.parseInt(latAndLng[0]);
				int longitudeE6 = Integer.parseInt(latAndLng[1]);

				myOverlay.addNewItem((new GeoPoint(latitudeE6, longitudeE6)), //Adiciona o ItemOverlay ao Mapa.
						null, null);
				addProximityAlert(latitudeE6/1E6, longitudeE6/1E6);//A cada ponto salvo no banco, ao preencher o mapa, adicionar ele ao alerta de proximidade.
				//Segundo a própria documentação das notificações, se o aparelho passar rapidamente por um ponto de alerta, pode ser que o alerta não seja exibido.
			}
		}
	}

	private ArrayList<String> lerTudoBanco() {
		int mode = this.MODE_PRIVATE; // Quem pode acessar?
		SharedPreferences prefLogin = this.getSharedPreferences(DbName, mode);

		ArrayList<String> listPoints = new ArrayList<String>();

		Set keys = prefLogin.getAll().keySet();

		for (Object object : keys) {
			listPoints.add((String) object);
		}

		return listPoints;
	}

	class MyOnClickListener implements OnClickListener {

		public void onClick(View v) {

			myOverlay.setPutMarksEnabled(markMap.isChecked());

		}

	}

	@Override
	public void onClick(View v) {
		if (v == bt_listarNotas) {

			/*
			 * Toda vez que clicar no botão listar notas tem que percorrer o
			 * banco de novo
			 */
			/* Povoar mapa com pontos salvos */
			List<String> test = lerTudoBanco();
			listDistinct = new ArrayList<String>();

			for (int i = 0; i < test.size(); i++) {
				String key = test.get(i).substring(0, test.get(i).length() - 1);
				if (!listDistinct.contains(key)) {
					listDistinct.add(key);
				}
			}

			listTitulos = new ArrayList<String>();
			listDesc = new ArrayList<String>();
			listDate = new ArrayList<String>();

			int mode = this.MODE_PRIVATE;
			SharedPreferences prefLogin = this.getSharedPreferences(DbName,
					mode);

			if (listDistinct.size() > 0) {
				for (int i = 0; i < listDistinct.size(); i++) {
					listTitulos.add(prefLogin.getString(listDistinct.get(i)
							+ "t", ""));
					listDesc.add(prefLogin.getString(listDistinct.get(i) + "d",
							""));
					listDate.add(prefLogin.getString(listDistinct.get(i) + "h",
							""));

				}

				listaDeNotas = new Dialog(this);
				listaDeNotas.setContentView(R.layout.listarnotas);
				// setContentView(R.layout.listarnotas);//Mostrar as notas em um
				// Dialog personalizado com a listview

				listaDeNotas.setTitle("Lista de Notas");
				listaDeNotas.show();

				listViewNotas = (ListView) listaDeNotas
						.findViewById(R.id.lista_notas);
				listViewNotas.setAdapter(new ArrayAdapter(this,
						android.R.layout.simple_list_item_1, listTitulos
								.toArray()));

				menuNota = new Dialog(this);

				/* Ao selecionar item na lista de notas */
				listViewNotas.setOnItemClickListener(this);

			}
		} else if (v == bt_excluir_nota) {
			System.out.println("chegou no evento click"); 
			myOverlay.deleteNoteOnClick(myOverlay.getItem(currentPositionNote).getPoint(), true);//Esse true é para informar ao método é uma chamada de outra classe q nao deve usar variáveis da classe onde o método reside.
			System.out.println("antes menu nota");
			menuNota.dismiss();
			System.out.println("depois menu nota");
			listaDeNotas.dismiss();
		} else if (v == bt_editar_nota) {
			editNoteByList();
			menuNota.dismiss();
			listaDeNotas.dismiss();
		} else if (v == bt_share_facebook) {
			
			myOverlay.shareFacebookOnClick(currentPositionNote);
		}else if(v == bt_edit)//edit nota final
		{
			editNoteFinal();
		}else if(v == bt_edit_cancel)
		{
			dialogEditNote.dismiss();
		}

	}

	@Override
	public void onItemClick(AdapterView<?> arg0, View arg1, int position,
			long id) {

		currentPositionNote = position;

		menuNota.setTitle("Menu nota");
		menuNota.setContentView(R.layout.notewithoutaproxlocales);
		menuNota.show();

		tv_title_nota = (TextView) menuNota.findViewById(R.id.tv_title_nota);
		tv_desc_nota = (TextView) menuNota.findViewById(R.id.tv_desc_nota);
		tv_date_nota = (TextView) menuNota.findViewById(R.id.tv_date_nota);

		System.out.println("title: " + listTitulos.get(position));
		System.out.println("Desc: " + listDesc.get(position));
		System.out.println("Date: " + listDate.get(position));

		tv_title_nota.setText("Título: " + listTitulos.get(position));
		tv_desc_nota.setText("Descrição: " + listDesc.get(position));
		String date = listDate.get(position);

		tv_date_nota.setText("Criação em: " + date.substring(0, 10) + " às "
				+ date.substring(11));

		bt_excluir_nota = (ImageButton) menuNota
				.findViewById(R.id.bt_excluir_nota);
		bt_editar_nota = (ImageButton) menuNota
				.findViewById(R.id.bt_editar_nota);
		bt_share_facebook = (ImageButton) menuNota
				.findViewById(R.id.bt_share_facebook);

		bt_excluir_nota.setOnClickListener(this);
		bt_editar_nota.setOnClickListener(this);
		bt_share_facebook.setOnClickListener(this);

	}

	public void DeleteNote(int position) {
		int mode = this.MODE_PRIVATE; // Quem pode acessar?
		SharedPreferences prefLogin = this.getSharedPreferences(DbName, mode);
		Editor editor = prefLogin.edit();

		// editor.remove(key);
	}

	public void zerarBanco() {
		int mode = this.MODE_PRIVATE; // Quem pode acessar?
		SharedPreferences prefLogin = this.getSharedPreferences(DbName, mode);
		Editor editor = prefLogin.edit();
		editor.clear();
		editor.commit();
	}

	public void editNoteByList()// Edit onde o usuário vê as informações da
								// nota, e nele há o botão editar que é o que
								// realmente modifica o banco.
	{
		System.out.println("Button editar nota");

		dialogEditNote = new Dialog(this);

		dialogEditNote.setContentView(R.layout.editnote);
		dialogEditNote.setTitle("Descrição");

		dialogEditNote.show();

		et_title_edit = (EditText) dialogEditNote
				.findViewById(R.id.et_edit_titulo);
		et_desc_edit = (EditText) dialogEditNote
				.findViewById(R.id.et_edit_descricao);

		bt_edit = (Button) dialogEditNote.findViewById(R.id.bt_edit);
		bt_edit_cancel = (Button) dialogEditNote
				.findViewById(R.id.bt_edit_cancelar);

		String[] infAboutPoint = readDBByPoint(myOverlay.getItem(currentPositionNote).getPoint());//Pega o GeoPoint atual a partir da posição da lista

		et_title_edit.setText(infAboutPoint[0]);
		et_desc_edit.setText(infAboutPoint[1]);

		bt_edit.setOnClickListener(this);
		bt_edit_cancel.setOnClickListener(this);
	}
	
	public String[] readDBByPoint(GeoPoint point)
	{
		int mode = this.MODE_PRIVATE; // Quem pode acessar?
		SharedPreferences prefLogin = this.getSharedPreferences(DbName, mode);
		
		String[] array = new String[3];
		
		array[0] = prefLogin.getString(point.toString()+"t", "");
		array[1] = prefLogin.getString(point.toString()+"d", "");
		array[2] = prefLogin.getString(point.toString()+"h", "");

		return array;
	}
	
	public void editNoteFinal()//Esse é o editar de verdade, após o usuário ver a tela com as informações da nota e preenchida com os dados do banco, ela pode editar e clicar no editar, que é a última interação da app com o usuário antes de modificar no banco.
	{
		System.out.println("botao edit");
		
		String title = et_title_edit.getText().toString();
		String desc = et_desc_edit.getText().toString();
		
		myOverlay.salvarBanco(myOverlay.getItem(currentPositionNote).getPoint(), title, desc); // O método na outra classe pode ser aproveitado pois não utiliza nenhum objeto a não ser os passados por parametro.
		
		Dialog dialogShowSucess = new Dialog(this);
		dialogShowSucess.setTitle("Salvo com Sucesso");
		dialogShowSucess.show();
		dialogEditNote.dismiss();
	}
	
	protected void addProximityAlert(double latitude, double longitude)
	{
		Intent intent = new Intent(PROX_ALERT_INTENT);
		PendingIntent proximityIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
		
		locationManager.addProximityAlert(latitude, longitude, POINT_RADIUS, PROX_ALERT_EXPIRATION, proximityIntent);
		IntentFilter filter = new IntentFilter(PROX_ALERT_INTENT);
		
		proximityReceiver.fillOutInfAboutPoint(this);
		registerReceiver(proximityReceiver, filter);
		
	}
}
